/**
 * 从粘贴事件中获取文本
 * @param t 粘贴事件
 */
export function getTextFromPaste(t: ClipboardEvent & { originalEvent?: ClipboardEvent }) {
  window.getSelection()?.deleteFromDocument();
  try {
    return window.clipboardData!.getData('Text');
  } catch (e) {
    return (t.originalEvent || t).clipboardData?.getData('text/plain') || '';
  }
}

/**
 * 获取 Range 对象
 */
export function getRange() {
  const selection = document.getSelection();
  if (selection?.getRangeAt && selection.rangeCount) {
    return selection.getRangeAt(0);
  } else {
    return (document as any).selection.createRange() as Range;
  }
}

/**
 * 选中节点
 * @param node 节点
 */
export function selectNode(node: Node) {
  if (document.createRange) {
    const range = document.createRange();
    range.selectNodeContents(node);
    range.collapse(false);
    const selection = window.getSelection();
    selection?.removeAllRanges();
    selection?.addRange(range);
  } else if ((document as any).selection) {
    const range = (document.body as any).createTextRange();
    range.moveToElementText(node);
    range.collapse(false);
    range.select();
  }
}

/**
 * 检测目标元素是否包含在容器元素中
 * @param container HTMLElement | null
 * @param target Node | null
 */
export function containsElement(container: HTMLElement | null, target: Node | null) {
  return (
    !(!target || !container) &&
    (container === target || containsElement(container, target.parentElement))
  );
}

export function fragmentFromHtml(html: string) {
  const div = document.createElement('div');
  div.innerHTML = html;

  const fragment = document.createDocumentFragment();

  while (div.firstChild) {
    fragment.appendChild(div.firstChild);
  }

  return fragment;
}

/**
 * 插入 html
 * @param container HTMLElement
 * @param html string
 */
export function insertHTML(container: HTMLElement, html: string) {
  const range = getRange();

  if (range && !containsElement(container, range.startContainer)) {
    selectNode(container);
  }
  container.focus();

  if (window.getSelection) {
    const selection = window.getSelection();
    if (selection?.getRangeAt && selection.rangeCount) {
      const range = selection.getRangeAt(0);
      range.deleteContents();

      const fragment = fragmentFromHtml(html);
      const lastChildNode = fragment.childNodes[fragment.childNodes.length - 1];

      range.insertNode(fragment);
      if (lastChildNode) {
        const clonedRange = range.cloneRange();
        clonedRange.setStartAfter(lastChildNode);
        clonedRange.collapse(true);
        selection.removeAllRanges();
        selection.addRange(clonedRange);
      }
    }
  } else {
    const selection = (document as any).selection;
    if (selection && 'Control' !== selection.type) {
      selection.createRange().pasteHTML(html);
    }
  }
}
